import re

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _

from yubikey.decrypt import RE_TOKEN, RE_AES_KEY, InvalidToken, InvalidAESKey

from models import Yubikey, generate_aes_key, generate_public_id

RE_PUBLIC_ID = re.compile(r'^[cbdefghijklnrtuv]{12}$')


class YubikeyForm(forms.ModelForm):
    public_id = forms.RegexField(label=_('Public ID'), regex=RE_PUBLIC_ID, min_length=12, max_length=12, initial=generate_public_id, error_messages={'invalid': _('The public ID can only contain the characters "cbdefghijklnrtuv".')})
    aes_key = forms.RegexField(label=_('AES key'), regex=RE_AES_KEY, min_length=32, max_length=32, initial=generate_aes_key, error_messages={'invalid': _('The AES key must be in hexadecimal encoding.')})

    class Meta:
        model = Yubikey
        fields = ('user', 'public_id', 'aes_key', 'remarks', 'is_active',)


class LoginForm(forms.Form):
    token = forms.RegexField(label=_('Yubikey'), regex=RE_TOKEN, min_length=34, max_length=64, error_messages={'invalid': _('The provided token is invalid.'), 'max_length': _('The provided token is invalid.'), 'min_length': _('The provided token is invalid.'),})

    def clean_token(self):
        self.user = authenticate(token=self.cleaned_data['token'])
        if self.user is None:
            raise forms.ValidationError(_('The provided token is invalid.'))


class PasswordForm(forms.Form):
    password = forms.CharField(label=_('Password'), required=True, widget=forms.PasswordInput())

    def __init__(self, *args, **kwargs):
        self.user = kwargs['user']
        del(kwargs['user'])
        super(PasswordForm, self).__init__(*args, **kwargs)

    def clean_password(self):
        if not self.user.check_password(self.cleaned_data['password']):
            raise forms.ValidationError(_('The provided password is incorrect.'))
